package net.quanter.shield.sample.elasticsearch.web.controller;

import net.quanter.shield.sample.elasticsearch.dao.entity.EsUser;
import net.quanter.shield.sample.elasticsearch.dao.repository.EsUserRepository;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/user")
public class EsUserController {
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Autowired
    private EsUserRepository EsUserRepository;

    public String getInstall(){
        return "https://www.elastic.co/guide/en/elasticsearch/reference/7.15/deb.html";
    }

    @PostMapping(value = "")
    public EsUser saveEsDoc(@RequestBody EsUser EsUser) {
//        IndexQuery indexQuery = new IndexQueryBuilder()
//                .withId(EsUser.getId().toString())
//                .withObject(EsUser)
//                .build();
//        EsUser result = EsUserRepository.index(indexQuery);

        IndexOperations indexOperationsEsUser = elasticsearchRestTemplate.indexOps(EsUser.getClass());
        if(!indexOperationsEsUser.exists()){
            indexOperationsEsUser.create();
        }
        return EsUserRepository.save(EsUser);
    }


    @GetMapping(value = "/query")
    public List<EsUser> query(String name) {
        List<EsUser> items = this.EsUserRepository.queryESUserByName(name);
        return items;
    }

    @GetMapping(value = "/search")
    public SearchHits<EsUser> search(String name) {
        NativeSearchQueryBuilder builder=
                new NativeSearchQueryBuilder()
                        .withQuery(QueryBuilders.matchPhraseQuery("name",name))
                ;
        SearchHits<EsUser> searchHits = this.elasticsearchRestTemplate.search(builder.build(),EsUser.class);
        return searchHits;
    }

    /**
    @RequestMapping(value = "/create-index", method = RequestMethod.POST)
    public Object createEsIndex() {
        elasticsearchRestTemplate.indexOps(EsUser.class).create();
        boolean index = elasticsearchRestTemplate.indexOps(EsUser.class).create();
        elasticsearchRestTemplate.putMapping(EsUser.class);

        System.out.println("创建索引结果是" + index);
        return index;
    }

    @RequestMapping(value = "/delete-index", method = RequestMethod.POST)
    public Object deleteEsIndex() {
        boolean deleteIndex = elasticsearchRestTemplate.deleteIndex(EsUser.class);
        System.out.println("删除索引结果是" + deleteIndex);
        return deleteIndex;
    }

    @RequestMapping(value = "/exist-index", method = RequestMethod.POST)
    public Object existEsIndex() {
        boolean existsIndex = elasticsearchRestTemplate.indexExists(EsUser.class);
        System.out.println("是否存在的结果是" + existsIndex);
        return existsIndex;
    }**/

    /**


    @RequestMapping(value = "/query-doc", method = RequestMethod.GET)
    public List<EsUser> queryByName(String name) {
        List<EsUser> result = EsUserRepository.queryEsUserByName(name);
        return result;
    }

    @RequestMapping(value = "/exist-doc", method = RequestMethod.GET)
    public Object existDoc(Long id) {
        return EsUserRepository.existsById(id);
    }


    @RequestMapping(value = "/query-doc/complex", method = RequestMethod.POST)
    @ApiOperation("根据名字查询文档")
    public Object queryByName(@RequestBody EsUser EsUser) {
        String desc = EsUser.getDesc();
        List<String> tags = EsUser.getTags();
        String name = EsUser.getName();
        // 先构建查询条件
        BoolQueryBuilder defaultQueryBuilder = QueryBuilders.boolQuery();
        if (StringUtils.isNotBlank(desc)){
            defaultQueryBuilder.should(QueryBuilders.termQuery("desc", desc));
        }
        if (StringUtils.isNotBlank(name)){
            defaultQueryBuilder.should(QueryBuilders.termQuery("name", name));
        }
        if (!CollectionUtils.isEmpty(tags)){
            for (String tag : tags) {
                defaultQueryBuilder.must(QueryBuilders.termQuery("tags", tag));
            }
        }

        // 分页条件
        PageRequest pageRequest = PageRequest.of(0,10);
        // 高亮条件
        HighlightBuilder highlightBuilder = getHighlightBuilder("desc", "tags");
        // 排序条件
        FieldSortBuilder sortBuilder = SortBuilders.fieldSort("age").order(SortOrder.DESC);
        //组装条件
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(defaultQueryBuilder)
                .withHighlightBuilder(highlightBuilder)
                .withPageable(pageRequest)
                .withSort(sortBuilder).build();

        SearchHits<EsUser> searchHits = elasticsearchRestTemplate.search(searchQuery, EsUser.class);

        // 高亮字段映射
        List<EsUserVo> userVoList = Lists.newArrayList();
        for (SearchHit<EsUser> searchHit : searchHits) {
            EsUser content = searchHit.getContent();
            EsUserVo EsUserVo = new EsUserVo();
            BeanUtils.copyProperties(content,EsUserVo);
            Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
            for (String highlightField : highlightFields.keySet()) {
                if (StringUtils.equals(highlightField,"tags")){
                    EsUserVo.setTags(highlightFields.get(highlightField));
                }else if(StringUtils.equals(highlightField,"desc")){
                    EsUserVo.setDesc(highlightFields.get(highlightField).get(0));
                }

            }
            userVoList.add(EsUserVo);
        }

        // 组装分页对象
        Page<EsUserVo> userPage = new PageImpl<>(userVoList,pageRequest,searchHits.getTotalHits());

        return userPage;
    }



    // 设置高亮字段
    private HighlightBuilder getHighlightBuilder(String... fields) {
        // 高亮条件
        HighlightBuilder highlightBuilder = new HighlightBuilder(); //生成高亮查询器
        for (String field : fields) {
            highlightBuilder.field(field);//高亮查询字段
        }
        highlightBuilder.requireFieldMatch(false);     //如果要多个字段高亮,这项要为false
        highlightBuilder.preTags("<span style=\"color:red\">");   //高亮设置
        highlightBuilder.postTags("</span>");
        //下面这两项,如果你要高亮如文字内容等有很多字的字段,必须配置,不然会导致高亮不全,文章内容缺失等
        highlightBuilder.fragmentSize(800000); //最大高亮分片数
        highlightBuilder.numOfFragments(0); //从第一个分片获取高亮片段

        return highlightBuilder;
    }**/
}
